import org.apache.hadoop.hive.ql.exec.UDF;

import java.util.Calendar;
import java.util.Date;

public class IdCardAgeUDF extends UDF {
    // 常量内部管理类
    private static final class CONSTAINS {
        // 失败标识符
        private static final String FAILED = "false";
        // 15位身份证格式校验正则
        private static final String REG_IDNUMBER_15 = "^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}";
        // 18位身份证格式校验正则
        private static final String REG_IDNUMBER_18 = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";

    }
    /**
     * 根据身份证号返回年龄
     * @param sfzjhm
     * @return false字符串表示未取到，其他表示取到的年龄
     */
    public String evaluate(String sfzjhm) {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 获取当前时间年月日
        int yearNow = calendar.get(Calendar.YEAR);
        // month从0开始，计算需要+1
        int monthNow = calendar.get(Calendar.MONTH) + 1;
        int dayNow = calendar.get(Calendar.DAY_OF_MONTH);
        // 15位身份证
        if(sfzjhm != null && sfzjhm.matches(CONSTAINS.REG_IDNUMBER_15)){
            // 获取身份证年月日
            int yearBirth = Integer.parseInt("19" + sfzjhm.substring(6 ,8));
            int monthBirth = Integer.parseInt(sfzjhm.substring(8,10));
            int dayBirth = Integer.parseInt(sfzjhm.substring(10,12));
            // 计算年龄
            int age = yearNow - yearBirth;
            if(monthNow <= monthBirth){ // 当前月份小，比较日期，否则直接取age
                if(dayNow < dayBirth){
                    age--;
                }
            }
            return String.valueOf(age);
        }
        // 18位身份证
        if(sfzjhm != null && sfzjhm.matches(CONSTAINS.REG_IDNUMBER_18)){
            // 获取身份证年月日
            int yearBirth = Integer.parseInt(sfzjhm.substring(6 ,10));
            int monthBirth = Integer.parseInt(sfzjhm.substring(10,12));
            int dayBirth = Integer.parseInt(sfzjhm.substring(12,14));
            // 计算年龄
            int age = yearNow - yearBirth;
            if(monthNow <= monthBirth){ // 当前月份小，比较日期，否则直接取age
                if(dayNow < dayBirth){
                    age--;
                }
            }
            return String.valueOf(age);
        }
        return CONSTAINS.FAILED;
    }
}